package co.th.helper.dao;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import org.apache.log4j.Logger;

import co.th.helper.common.CommonUtils;
import co.th.helper.jdbc.JdbcTemplate;
import co.th.helper.jdbc.mapper.DepartmentOfHospitalRowMapper;
import co.th.helper.model.DepartmentOfHospital;
import co.th.helper.model.Hospital;

public class DepartmentOfHospitalDAO extends JdbcTemplate<DepartmentOfHospital>{

	private static Logger _logger = Logger.getLogger(DepartmentOfHospitalDAO.class);
	
	public List<DepartmentOfHospital> findAll() throws Exception{
		try {
			return findByCriteria(null);
		} catch (Exception ex) {
			_logger.error("Exception : " + ex.getMessage());
			throw new RuntimeException("Can't get all Department of Hospital Data.");
		}
	}
	
	public DepartmentOfHospital findByPK(BigDecimal hospitalCode, BigDecimal departmentOfHospitalCode) throws Exception{
		try {
			DepartmentOfHospital deptOfHosp = new DepartmentOfHospital();
			deptOfHosp.setHospitalCode(hospitalCode);
			deptOfHosp.setHospitalDepartmentCode(departmentOfHospitalCode);
			
			List<DepartmentOfHospital> list = findByCriteria(deptOfHosp);
			if (null == list || list.isEmpty()){
				throw new Exception("Record not found.");
			}
			return list.get(0);
		} catch (Exception ex) {
			_logger.error("Exception : " + ex.getMessage());
			throw new RuntimeException("Cat not get Department of Hospital");
		}
	}
	
	public List<DepartmentOfHospital> findByCriteria(DepartmentOfHospital depatOfHosp) throws Exception{
		try {
			StringBuffer sql = new StringBuffer("select * from hospital_department where 1=1 ");
			List<Object> paramObj = new ArrayList<Object>(0);
			
			if (null != depatOfHosp){
				int index = 0;
				if (null != depatOfHosp.getHospitalCode() && depatOfHosp.getHospitalCode().intValue() > 0){
					sql.append(" AND hospital_code = ? ");
					paramObj.add(index++, depatOfHosp.getHospitalCode());
				}
				if (null != depatOfHosp.getHospitalDepartmentCode() && depatOfHosp.getHospitalDepartmentCode().intValue() > 0){
					sql.append(" AND hospital_dept_code = ? ");
					paramObj.add(index++, depatOfHosp.getHospitalDepartmentCode());
				}
				if (!CommonUtils.chkIsnull(depatOfHosp.getHospitalDepartmentNameTh())){
					sql.append(" AND hospital_dept_name_th = ? ");
					paramObj.add(index++, depatOfHosp.getHospitalDepartmentNameTh());
				}
				if (!CommonUtils.chkIsnull(depatOfHosp.getHospitalDepartmentNameEn())){
					sql.append(" AND hospital_dept_name_en = ? ");
					paramObj.add(index++, depatOfHosp.getHospitalDepartmentNameEn());
				}
				if (!CommonUtils.chkIsnull(depatOfHosp.getDirector())){
					sql.append(" AND director_code = ? ");
					paramObj.add(index++, depatOfHosp.getDirector());
				}
				if (!CommonUtils.chkIsnull(depatOfHosp.getBedCapacityMin())){
					sql.append(" AND bed_capacity_min = ? ");
					paramObj.add(index++, depatOfHosp.getBedCapacityMin());
				}
				if (!CommonUtils.chkIsnull(depatOfHosp.getBedCapacityMax())){
					sql.append(" AND bed_capacity_max = ? ");
					paramObj.add(index++, depatOfHosp.getBedCapacityMax());
				}
			}
			return this.queryList(sql.toString(), CommonUtils.convListToArray(paramObj), new DepartmentOfHospitalRowMapper());
		} catch (Exception ex) {
			_logger.error("Exception : " + ex.getMessage());
			throw new RuntimeException("Can't get Department of Hospital Data.");
		}
	}
	
	public synchronized DepartmentOfHospital insert(DepartmentOfHospital departmentOfHospital) throws Exception{
		try {
			if (CommonUtils.chkIsnull(departmentOfHospital.getHospitalCode())){
				throw new Exception("No primary key (Hospital Code).");
			}
			departmentOfHospital.setHospitalDepartmentCode(genDepartmentCode(departmentOfHospital.getHospitalCode()));
			
			final String sql = "INSERT INTO hospital_department (hospital_code, hospital_dept_code, hospital_dept_name_th, hospital_dept_name_en, director_code, bed_capacity_min, bed_capacity_max, create_by, create_date, update_by, update_date) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
			Object[] params = new Object[11];
			params[0] = departmentOfHospital.getHospitalCode();
			params[1] = departmentOfHospital.getHospitalDepartmentCode();
			params[2] = departmentOfHospital.getHospitalDepartmentNameTh();
			params[3] = departmentOfHospital.getHospitalDepartmentNameEn();
			params[4] = departmentOfHospital.getDirector();
			params[5] = departmentOfHospital.getBedCapacityMin();
			params[6] = departmentOfHospital.getBedCapacityMax();
			params[7] = departmentOfHospital.getCreateBy();
			params[8] = departmentOfHospital.getCreateDate();
			params[9] = departmentOfHospital.getUpdateBy();
			params[10] = departmentOfHospital.getUpdateDate();
			
			_logger.info("SQL : " + sql);
			int rowOfProcess = this.saveUnique(sql, params);
			if (rowOfProcess < 1){
				throw new Exception("Can't save Department of Hospital data.");
			}
			return departmentOfHospital;
		} catch (Exception ex) {
			_logger.error("Exception : " + ex.getMessage());
			throw ex;
		}
	}
	
	public int update(DepartmentOfHospital departmentOfHospital) throws Exception{
		try {			
			if (null == departmentOfHospital.getHospitalCode() || departmentOfHospital.getHospitalCode().intValue() <= 0){
				throw new Exception("No primary key (Hospital Code).");
			}else if (null == departmentOfHospital.getHospitalDepartmentCode() || departmentOfHospital.getHospitalDepartmentCode().intValue() <= 0){
				throw new Exception("No primary key (Department Of Hospital Code).");
			}

			StringBuffer sql = new StringBuffer("UPDATE hospital_department SET ");
			List<Object> paramObj = new ArrayList<Object>(0);
			
			int index = 0;
			sql.append(" update_date = ?  ");
			paramObj.add(index++, new java.sql.Date(Calendar.getInstance().getTime().getTime()));
			if (!CommonUtils.chkIsnull(departmentOfHospital.getHospitalDepartmentNameTh())){
				sql.append(" , hospital_dept_name_th = ? ");
				paramObj.add(index++, departmentOfHospital.getHospitalDepartmentNameTh());
			}
			if (!CommonUtils.chkIsnull(departmentOfHospital.getHospitalDepartmentNameEn())){
				sql.append(" , hospital_dept_name_en = ? ");
				paramObj.add(index++, departmentOfHospital.getHospitalDepartmentNameEn());
			}
			if (null != departmentOfHospital.getDirector() && departmentOfHospital.getDirector().intValue() > 0){
				sql.append(" , director_code = ? ");
				paramObj.add(index++, departmentOfHospital.getDirector());
			}
			if (null != departmentOfHospital.getBedCapacityMin() && departmentOfHospital.getBedCapacityMin().intValue() > 0){
				sql.append(" , bed_capacity_min = ? ");
				paramObj.add(index++, departmentOfHospital.getBedCapacityMin());
			}
			if (null != departmentOfHospital.getBedCapacityMax() && departmentOfHospital.getBedCapacityMax().intValue() > 0){
				sql.append(" , bed_capacity_max = ? ");
				paramObj.add(index++, departmentOfHospital.getBedCapacityMax());
			}
			
			sql.append(" WHERE  hospital_code  = ? AND  hospital_dept_code  = ? ");
			paramObj.add(index++, departmentOfHospital.getHospitalCode());
			paramObj.add(index++, departmentOfHospital.getHospitalDepartmentCode());
			
			return updateUnique(sql.toString(), CommonUtils.convListToArray(paramObj), new DepartmentOfHospitalRowMapper());
		} catch (Exception ex) {
			_logger.error("Exception : " + ex.getMessage());
			throw new RuntimeException("Can't update Department Of Hospital Data.");
		}
	}
	
	public int delete(BigDecimal hospitalCode, BigDecimal departmentOfHospitalCode) throws Exception{
		try {	
			/* Validate PK */
			if (hospitalCode == null || hospitalCode.intValue() <= 0){
				throw new Exception("No primary key (Hospital Code).");
			}else if (departmentOfHospitalCode == null || departmentOfHospitalCode.intValue() <= 0){
				throw new Exception("No primary key (Department Of Hospital Code).");
			}
			
			final String sql = "DELETE FROM hospital_department WHERE hospital_code = ? AND hospital_dept_code = ?";
			Object[] param = new Object[]{hospitalCode, departmentOfHospitalCode};
			return updateUnique(sql.toString(), param, new DepartmentOfHospitalRowMapper());
		} catch (Exception ex) {
			_logger.error("Exception : " + ex.getMessage());
			throw new RuntimeException("Can't delete Department Of Hospital Data.");
		}
	}
	
	private BigDecimal genDepartmentCode(BigDecimal hospitalCode) throws Exception{
		final String sql = "SELECT MAX(hospital_dept_code) AS hospital_dept_code FROM hospital_department WHERE hospital_code = ?";
		_logger.debug("SQL : " + sql);
		DepartmentOfHospital objRow = queryUnique(sql, new Object[]{hospitalCode}, new DepartmentOfHospitalRowMapper());
		BigDecimal depatmentCode = BigDecimal.valueOf(objRow.getHospitalDepartmentCode().intValue() + 1);
		
		HospitalDAO hospitalDAO = new HospitalDAO();
		Hospital hospital = hospitalDAO.findByPK(hospitalCode);
		
		String codeGen = hospital.getRegion().intValue() + "";
		codeGen = codeGen + CommonUtils.convBigDecimalToString(hospital.getHospitalCode(), 3);
		codeGen = codeGen + CommonUtils.convBigDecimalToString(depatmentCode, 2);
		return BigDecimal.valueOf(Integer.parseInt(codeGen));
	}
}
